import os
from typing import Dict, List, Optional, Type

from fastapi import FastAPI
from pydantic import HttpUrl
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.staticfiles import StaticFiles
from tortoise import Model

from . import template
from .constants import BASE_DIR
from .middlewares import locale_processor
from .resources import Dropdown
from .resources import Model as ModelResource
from .resources import Resource
from .routes import router


class FastAdmin(FastAPI):
    ADMIN_PATH: str
    resources: List[Type[Resource]] = []
    model_resources: Dict[Type[Model], Type[Resource]] = {}

    def configure(
        self,
        logo_url: Optional[HttpUrl] = None,
        default_locale: str = "en_US",
        admin_path: str = "/admin",
        template_folders: Optional[List[str]] = None,
    ):
        template.set_global_env("LOGO_URL", logo_url)
        template.set_global_env("ADMIN_PATH", admin_path)
        template.set_locale(default_locale)
        self.ADMIN_PATH = admin_path
        if template_folders:
            template.add_template_folder(*template_folders)

    def register_resources(self, *resource: Type[Resource]):
        for r in resource:
            self.register(r)

    def _set_model_resource(self, resource: Type[Resource]):
        if issubclass(resource, ModelResource):
            self.model_resources[resource.model] = resource
        elif issubclass(resource, Dropdown):
            for r in resource.resources:
                self._set_model_resource(r)

    def register(self, resource: Type[Resource]):
        self._set_model_resource(resource)
        self.resources.append(resource)

    def get_model_resource(self, model: Type[Model]):
        return self.model_resources[model]


app = FastAdmin(
    title="FastAdmin",
    description="A fast admin dashboard based on fastapi and tortoise-orm with tabler ui.",
)
app.mount(
    "/static",
    StaticFiles(directory=os.path.join(BASE_DIR, "static")),
    name="static",
)
app.add_middleware(BaseHTTPMiddleware, dispatch=locale_processor)
app.include_router(router, prefix="")
app.include_router(router)
